<?php
/**
 * Created by PhpStorm.
 * User: qinshuguo
 * Date: 2017/6/30
 * Time: 14:33
 */

namespace App\Api\Auth\Services;

use App\Api\Auth\Models\UserOpenId;
use App\Api\Auth\Models\Users;
use App\User;
use Illuminate\Contracts\Validation\UnauthorizedException;
use Rocky\Wxapp\Wxapp;
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
use Validator;

class AuthService
{
    public function wxappLogin($appId, $appSecret, $jsCode, $userInfoData = null, $userInfoIv = null)
    {

        //get Session Key and OpenId
        $session    = Wxapp::codeToSession($appId, $appSecret, $jsCode);
        $sessionKey = data_get($session, 'session_key');
        $openId     = data_get($session, 'openid');
        if (!$sessionKey) {
            throw new \LogicException('微信登录失败', 10);
        }

        $userInfo = Wxapp::decrypt($appId, $sessionKey, $userInfoData, $userInfoIv);
        $userInfo = json_decode(data_get($userInfo, 'data'), true);

        //get User by OpenId
        $userOpenId = UserOpenId::where('open_id', $openId)->first();
        $user       = data_get($userOpenId, 'user');
        if ($user) {
            //user exists. update session_key and return user.
            $userOpenId->session_key = $sessionKey;
            $userOpenId->save();
            $result          = $user->toArray();
            $result['token'] = data_get($user, 'api_token');
            return $result;
        }

        //user not exists. create user by userInfo
        if (!$userInfo) {
            throw new \LogicException('微信用户信息获取失败', 20);
        }

        $token = str_random(32);
        $user  = User::create([
            'name'      => data_get($userInfo, 'nickName', ''),
            'real_name' => data_get($userInfo, 'nickName', ''),
            'data'      => json_encode(['wxapp' => $userInfo]),
            'api_token' => $token,
            'status'    => 0,
        ]);
        $user->openIds()->create([
            'open_id'     => $openId,
            'session_key' => 1,
        ]);
        $result          = $user->toArray();
        $result['token'] = $token;

        return $result;
    }

    /**
     * 获取用户实名认证的照片
     * @param $userId
     * @return array
     */
    public static function fetchRealAuthPhoto($userId)
    {
        $handRandomName = str_random() . '.jpg';
        $faceRandomName = str_random() . '.jpg';
        $backRandomName = str_random() . '.jpg';
        $path           = storage_path() . '/upload/realAuth/user-' . $userId;
        $cmd            = "ln -s $path-hand.jpeg $handRandomName;";
        $cmd            .= "ln -s $path-face.jpeg $faceRandomName;";
        $cmd            .= "ln -s $path-back.jpeg $backRandomName;";
        `$cmd`;
        return [
            'hand' => BASE_URL . '/' . $handRandomName,
            'face' => BASE_URL . '/' . $faceRandomName,
            'back' => BASE_URL . '/' . $backRandomName,
        ];
    }

    public static function getUserRole(User $user, $field = 'name')
    {
        $roles = $user->roles()->pluck($field);
        if (!empty($roles)) {
            $roles = $roles->toArray();
        } else {
            $roles = [];
        }
        $user          = $user->toArray();
        $user['roles'] = $roles;
        return $user;
    }

    public static function createUserExtra($channel, $options = [], $cityId = '')
    {
        $userName = data_get($options, 'name');
        $userId = data_get($options, 'user_id');
        $channel = strtoupper($channel);
        $parentId = env('MERCHANT_'.$channel.'EJ_ID', env('MERCHANT_GREJ_ID'));
        if (!empty($cityId)) {
            $parentId = $cityId;
        }
        try {
            \App\UserExtra::create([
                'user_id' => $userId,
                'parent_id' => $parentId,
                'grand_parent_id' => env('MERCHANT_'.$channel.'_ID', env('MERCHANT_GR_ID')),
                'shop' => $userName,
            ]);
        } catch (\Exception $e) {
            if ($e->getCode() == 23000 and strpos($e->getMessage(), '1062')) {
                throw new \LogicException("该用户已关联其他渠道", 230);
            } else {
                throw $e;
            }
        }
    }

    public static function resetPassword($params)
    {
        $validator = Validator::make($params, [
            'id'       => ['required', 'integer', 'exists:users'],
            'password' => 'required|min:6',
        ]);
        if ($validator->fails()) {
            throw new \LogicException('请核对信息');
        }
        $result = User::where('id', '=', data_get($params, 'id'))
            ->update(['password' => bcrypt(data_get($params, 'password'))]);
        return $result;
    }

    public static function userUpdate($params)
    {
        $id = data_get($params, 'id');
        unset($params['id']);
        //参数校验
        $fillable = [
            'email', 'mobile', 'rebate_mobile', 'wechat_id', 'weibo_id',
            'real_name', 'address', 'description', 'status', 'oauth_id',
        ];
        foreach (array_keys($params) as $key) {
            if (!in_array($key, $fillable)) throw new \LogicException('非法参数，无法更新');
        }
        //手机号，邮箱唯一校验 待优化先实现。。
        if ($mobile = data_get($params, 'mobile')) {
            $user = User::query()
                ->where('id', '!=', $id)
                ->where('mobile',$mobile)
                ->first();
            if ($user) throw new \LogicException('用户手机号已存在，请核对');
        }
        if ($email = data_get($params, 'email')) {

            $user = User::query()
                ->where('id', '!=', $id)
                ->where('email',$email)
                ->first();
            if ($user) throw new \LogicException('用户邮箱已存在，请核对');
        }
        $result = User::query()
            ->where('id', $id)
            ->update($params);
        return $result;
    }

    public static function authByToken($token)
    {
        $user = User::where('api_token', '=', $token)
            ->first();
        if (empty($user)) {
            throw new UnauthorizedHttpException('认证失败, 请先登录');
        }
        return $user;
    }

    public static function getShopId($user)
    {
        $bUser = Users::where('id', '=', data_get($user, 'id'))
            ->first();

        return data_get($bUser, 'shop_id', '');
    }
}